package com.qianfeng.smartplatform.websocket;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.HashMultimap;
import com.qianfeng.smartplatform.event.DevicePowerCommandEvent;
import com.qianfeng.smartplatform.event.SysHumitureCheckEvent;
import com.qianfeng.smartplatform.pojo.SysHumiture;
import com.qianfeng.smartplatform.service.SysHumitureService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by Jackiechan on 2022/6/1 14:46
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */
@Component
@EnableAsync(proxyTargetClass = true)
public class MyDHT11Handler extends MyBaseWebSocketHandler {



    //创建一个map,泛型其实是一个集合
    HashMultimap<String, SysHumiture> humitureHashMultimap = HashMultimap.create();


    private static Map<String, Long> heartbeatTime = new ConcurrentHashMap<>();

    private static Map<String, WebSocketSession> allClient = new ConcurrentHashMap<>();


    private SysHumitureService sysHumitureService;

    @Autowired
    public void setSysHumitureService(SysHumitureService sysHumitureService) {
        this.sysHumitureService = sysHumitureService;
    }

    private ObjectMapper objectMapper;

    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }


    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        super.handleTextMessage(session, message);
//        /获取到传递过来的温湿度的json数据
        String humtepJson = message.getPayload();
        System.err.println("MyDHT11Handler中的方法handleTextMessage 执行了" + humtepJson);
        //收到的都是温湿度的数据,我们需要保存到数据库中
        SysHumiture sysHumiture = objectMapper.readValue(humtepJson, SysHumiture.class);
        //设置设备的id
        String deviceId = (String) session.getAttributes().get("name");
        sysHumiture.setDeviceId(deviceId);
        //设置上传数据的时间
        sysHumiture.setUploadTime(new Date());
        //时刻将数据写入到数据库会导致数据的并发比较高,其实我们允许丢失一部分数据
        //在这里我们就把数据保存到内存中,每隔一段时间批量写入到数据库
        // sysHumitureService.addsysHumiture(sysHumiture);
        humitureHashMultimap.put(deviceId, sysHumiture);
    }

    @EventListener
    @Async
    public void onEvent(SysHumitureCheckEvent event) {
//        humitureHashMultimap.forEach((deviceId,data)->{
//            System.err.println(deviceId+"------>" + data);
//            //
//        });
        //批量插入到数据库
        //INSERT INTO XXX VALUES (DASDASD,DASDAS,DAS,DASD,DASD,DASD,DASASD)
        Collection<SysHumiture> values = humitureHashMultimap.values();
        if (values == null || values.size() == 0) {
            return;
        }
        //用户新的集合接收数据,防止下面清空的时候导致数据消失
        ArrayList<SysHumiture> list = new ArrayList<>(values);
        humitureHashMultimap.clear();//清空数据

        //计算平均值,触发任务
        //比如我们约定,如果温度超过30度就给设备发送开的命令, 如果低于25度就发送关的命令
//        double sum = 0;
//        for (SysHumiture value : values) {
//            sum += value.getTemperature();
//        }
//        double avg = sum / values.size();
        //计算数据的平均值
     //   double sum = list.stream().mapToDouble(SysHumiture::getTemperature).sum();
        double avg = list.stream().mapToDouble(SysHumiture::getTemperature).average().getAsDouble();

        if (avg >= 30) {
           // System.err.println("打开空调");
            getContext().publishEvent(new DevicePowerCommandEvent("1234567890", "0"));
        } else if (avg <= 25) {
           // System.err.println("关闭空调");
            getContext().publishEvent(new DevicePowerCommandEvent("1234567890", "1"));
        }
        sysHumitureService.multiAdd(list);//批量添加

    }


    @Override
    public boolean isNeedUpdateOnline() {
        return true;
    }

    @Override
    protected Map<String, Long> getHeartbeatTime() {
        return heartbeatTime;
    }

    @Override
    protected Map<String, WebSocketSession> getAllClient() {
        return allClient;
    }
}
